package com.jwater.launch;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import sun.misc.Launcher;

/**
 * @description:类加载工具
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public final class LoaderUtils {
    /**
     * 加载jar包
     *
     * @param jarFile
     * @throws Exception
     */
    public static void addJar(File jarFile) throws Exception {
        LoadJar.loadJarFile(jarFile);
    }

    /**
     * 加载目录下所有jar包
     *
     * @param dir
     * @param recursive
     * @throws Exception
     */
    public static void addJarDir(File dir, boolean recursive) throws Exception {
        LoadVersionJar.loadCurrentVersionJar(dir, recursive);
    }

    /**
     * 将目录加载到类路径下
     *
     * @param dir
     * @throws Exception
     */
    public static void loadDirToClasspath(File dir) throws Exception {
        LoadJar.loadJarFile(dir);
    }

    /**
     * 是否存在类
     *
     * @param className
     * @return
     */
    public static boolean existClass(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }

    /**
     * 调用类的main函数
     *
     * @param className
     * @param args
     * @throws Throwable
     */
    public static void exeMain(String className, String[] args) throws Throwable {
        Class<?> mainClass = Class.forName(className);
        Method main = mainClass.getMethod("main", new Class[]{Array.newInstance(String.class, 0).getClass()});
        try {
            main.invoke(null, new Object[]{args});
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    /**
     * 获取jvm中所有已经存在的jar包信息
     *
     * @return
     */
    @SuppressWarnings({"resource"})
    public static List<String> getAllJars() {
        List<String> list = new ArrayList<String>();
        URL[] urls = Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
            list.add(urls[i].toExternalForm());
        }
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        while (classLoader != null) {
            if (classLoader instanceof URLClassLoader) {
                URLClassLoader urlClassLoader = (URLClassLoader) classLoader;
                urls = urlClassLoader.getURLs();
                for (int i = 0; i < urls.length; i++) {
                    list.add(urls[i].toExternalForm());
                }
            }
            classLoader = classLoader.getParent();
        }
        return list;
    }
}